﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Microsoft.Samples.Kinect.KinectExplorer;
using Microsoft.Samples.Kinect.WpfViewers;

namespace ZeroTouchUI
{
    /// <summary>
    /// Interaction logic for AddGesture.xaml
    /// </summary>
    public partial class AddGesture : Window
    {
        private readonly Uri iconUri = new Uri("pack://application:,,,/KinectExplorer.ico", UriKind.RelativeOrAbsolute);
        public Microsoft.Samples.Kinect.KinectExplorer.KinectExplorer explorer;
        private GestureRecorder recorder;
        KeyValuePair<Gesture, Action> newGesture;
        Profile profile;
        public MainWindow mainWindow;
        Edit editWindow;
        GestureCanvas canvas;
        //variables used for edit mode
        bool editMode = false;
        Gesture originalGesture;
        Action originalAction;

        public AddGesture(Profile p, MainWindow mW, Edit e)
        {
            InitializeComponent();
            Gesture g = new Gesture();
            Action a = new Action();
            newGesture = new KeyValuePair<Gesture, Action>(g, a);
            profile = p;
            mainWindow = mW;
            editWindow = e;
            canvas = new GestureCanvas();
            gestureCanvas.Children.Add(canvas);
            originalGesture = new Gesture();
            originalAction = new Action();

            //populate the combobox of actions
            List<Action> action_list = profile.getActionList();
            foreach (Action aa in action_list)
            {
                ComboBoxItem cbi = new ComboBoxItem();
                cbi.Content = aa.Name;
                CommandList.Items.Add(cbi);
            }

        }

        public AddGesture(Profile p, MainWindow mW, Edit e, Gesture g, Action a)
        {
            InitializeComponent();
            originalGesture = g;
            originalAction = a;
            newGesture = new KeyValuePair<Gesture, Action>(g, a);
            profile = p;
            mainWindow = mW;
            editWindow = e;
            canvas = new GestureCanvas();
            gestureCanvas.Children.Add(canvas);
            GestureName.Text = g.Name;
            CommandList.Items.MoveCurrentTo(CommandList.FindName(a.Name));
            /*int index = -1;
            for (int x = 0; x < CommandList.Items.Count; x++)
            {
                ComboBoxItem cbi = (ComboBoxItem)CommandList.Items[x];
                if ((string)cbi.Content == a.Info)
                    index = x;
            }
            CommandList.SelectedIndex = index;*/
            editMode = true;

            //populate the combobox of actions
            List <Action> action_list = profile.getActionList();
            foreach (Action aa in action_list)
            {
                ComboBoxItem cbi = new ComboBoxItem();
                cbi.Content = aa.Name;
                CommandList.Items.Add(cbi);
            }
        }
        
        private void CommandList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (CommandList.SelectedIndex >= 0)
            {
                ComboBoxItem cbi = (ComboBoxItem)CommandList.SelectedValue;
                newGesture.Value.Name = (string)cbi.Content;
            }
        }


        private void Cancel_Click(object sender, RoutedEventArgs e)
        {
            if (editMode)
            {
                this.Close();
            }
            else
                this.Close();
        }


        private void AddGesture_Click(object sender, RoutedEventArgs e)
        {
            if (editMode)
            {
                //We still need to make sure all the information is filled out, but only want to update the information in profile
                if (newGesture.Key.Name != "" && newGesture.Value.Name != "" && /*newGesture.Value.Info != "" &&*/
                    ((newGesture.Key.leftGesture != null && newGesture.Key.leftGesture.Count > 0) || (newGesture.Key.rightGesture != null && newGesture.Key.rightGesture.Count > 0)))
                {
                    foreach (Gesture g in profile.getDictionary().Keys)
                        if (g.Name == originalGesture.Name)
                        {
                            g.leftGesture = newGesture.Key.leftGesture;
                            g.rightGesture = newGesture.Key.rightGesture;
                            g.Name = newGesture.Key.Name;
                            profile.getDictionary()[g].CustomData = newGesture.Value.CustomData;
                            profile.getDictionary()[g].Info = newGesture.Value.Info;
                            profile.getDictionary()[g].Name = newGesture.Value.Name;
                        }
                    editWindow.Update();
                    Dollar.templates = profile.getDictionary();
                    this.Close();
                }
                else
                {
                    DataPrompt dp = new DataPrompt();
                    dp.ShowDialog();
                }
            }
            else
            {
                // Ensure the new gesture has a name, proper action, and recorded gesture tied to it
                if (newGesture.Key.Name != "" && newGesture.Value.Name != "" /*&& newGesture.Value.Info != ""*/ &&
                    ((newGesture.Key.leftGesture != null && newGesture.Key.leftGesture.Count > 0) || (newGesture.Key.rightGesture != null && newGesture.Key.rightGesture.Count > 0)))
                {
                    if (profile.getDictionary().Any(g => g.Key.Name.ToLower() == newGesture.Key.Name.ToLower()))
                    {
                        NameTaken nt = new NameTaken();
                        nt.ShowDialog();
                    }
                    else
                    {
                        mainWindow.profile.AddGesture(newGesture.Key, newGesture.Value);
                        editWindow.Update();
                        Dollar.templates = profile.getDictionary();
                        this.Close();
                    }
                }
                else
                {
                    DataPrompt dp = new DataPrompt();
                    dp.ShowDialog();
                }
            }
        }

        private void GestureName_TextChanged(object sender, TextChangedEventArgs e)
        {
            newGesture.Key.Name = GestureName.Text;
        }

        private void record_Click(object sender, RoutedEventArgs e)
        {
            //Gesture Recording Here
            //Clicking the button again should probably overwrite the saved gesture with the new gesture.
            ActivateExplorer();
            if (explorer.sensorItems != null &&
                explorer.sensorItems.Count > 0 &&
                explorer.sensorItems[0].Sensor != null)
            {
                recorder = new GestureRecorder(this.mainWindow) { Kinect = explorer.sensorItems[0].Sensor };
                recorder.Saved += new SavedEventHandler(recorder_Saved);
                recorder.Closed += new EventHandler(recorder_Closed);
                recorder.ShowDialog();
            }
        }

        private void ActivateExplorer()
        {
            explorer = mainWindow.explorer;

            if (explorer == null)
            {
                explorer = new Microsoft.Samples.Kinect.KinectExplorer.KinectExplorer { Icon = BitmapFrame.Create(iconUri) };
                explorer.Closed += new EventHandler(Explorer_Closed);
                explorer.Show();
            }
            else
            {
                explorer.Activate();
            }
        }

        private void Explorer_Closed(object sender, EventArgs e)
        {
            foreach (KinectSensorItem kinect in explorer.sensorItems)
            {
                if (kinect.Window != null)
                {
                    kinect.Window.Close();
                }
            }

            if (this.recorder != null)
            {
                this.recorder.Close();
            }

            explorer = null;
        }

        private void recorder_Saved(object sender, EventArgs e)
        {
            if (recorder.leftGesture != null && recorder.leftGesture.Count > 0)
            {
                newGesture.Key.leftGesture = recorder.leftGesture;
            }
            else
            {
                newGesture.Key.leftGesture = new List<Point>();
            }

            if (recorder.rightGesture != null && recorder.rightGesture.Count > 0)
            {
                newGesture.Key.rightGesture = recorder.rightGesture;
            }
            else
            {
                newGesture.Key.rightGesture = new List<Point>();
            }

            gestureCanvas.Children.Remove(canvas);
            canvas = new GestureCanvas { gesture = newGesture.Key };
            gestureCanvas.Children.Add(canvas);
            recorder.Close();
        }

        private void recorder_Closed(object sender, EventArgs e)
        {
            this.Activate();
        }

        private void add_new_action_Click(object sender, RoutedEventArgs e)
        {
            // Open a dialog to add a new action
            AddNewAction add_action = new AddNewAction(CommandList, newGesture, profile);
            add_action.ShowDialog();
        }
    }
}
